﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal class ExtRst
    {
        private ushort cb;
        private ushort reserved;
        private uint phs;
        private RPHSSub rphssub;
        private List<PhRuns> rgphruns;

        public ExtRst(BinaryReader reader)
        {
#if DEBUG
            var pos = reader.BaseStream.Position;
#endif
            Debug.WriteLine("Reading " + GetType());
            this.reserved = reader.ReadUInt16();
            Contract.Assert((reserved == 1));
            this.cb = reader.ReadUInt16();
            this.phs = reader.ReadUInt32();
            this.rphssub = new RPHSSub();
            this.rphssub.Read(reader);
            this.rgphruns = new List<PhRuns>();
            Debug.WriteLine("In reading " + GetType() + " " + rphssub.ActualRunCount);
            for (int i = 0; i < rphssub.ActualRunCount; i++ )
            {
                this.rgphruns.Add(new PhRuns(reader));
            }
#if DEBUG
            Contract.Assert(reader.BaseStream.Position == pos + Length);
#endif
        }

        public int Length
        {
            get { int result = 2 + 2 + 4 + rphssub.Length + Enumerable.Sum(rgphruns, r => r.Length);
                return result;
            }
        }

        public void Write(BinaryWriter writer)
        {
            throw new NotImplementedException();
        }

    }

    internal class PhRuns
    {
        private short ichFirst;
        private short ichMom;
        private short cchMom;

        public PhRuns(BinaryReader reader)
        {
            this.Read(reader);
        }

        public ushort Length
        {
            get { return 6; }
        }

        private void Read(BinaryReader reader)
        {
            this.ichFirst = reader.ReadInt16();
            this.ichMom = reader.ReadInt16();
            this.cchMom = reader.ReadInt16();
        }
    }

    internal class RPHSSub
    {
        private ushort crun;
        private ushort cch;
        private LPWideString st;
        internal int ActualRunCount
        {
            get
            {
                return crun;
            }
        }

        public int Length
        {
            get { return 2 + 2 + st.ByteCount; }
        }

        public void Read(BinaryReader reader)
        {
            this.crun = reader.ReadUInt16();
            this.cch = reader.ReadUInt16();
            this.st = new LPWideString();
            this.st.Read(reader);
        }
    }
}